package com.wzp.util.highconcurrency;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

/**
 * @author wangzhengpeng
 */
public class CompletableFutureTest {

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        System.out.println("------------WhenCompleteTest--------------");
        WhenCompleteTest();

        System.out.println("------------ThenApplyTest--------------");
        ThenApplyTest();

        System.out.println("------------ThenAcceptTest--------------");
        ThenAcceptTest();

        System.out.println("------------ThenCompose--------------");
        ThenCompose();
    }

    /**
     * thenCompose方法可以将两个异步操作进行流水操作
     */
    private static void ThenCompose() throws InterruptedException, ExecutionException {
        CompletableFuture<Integer> result = CompletableFuture.supplyAsync(CompletableFutureTest::randomInteger)
                .thenCompose(i -> CompletableFuture.supplyAsync(() -> i * 10));
        System.out.println(result.get());
    }

    /**
     * thenApply也可以归类为对结果的处理，thenAccept和thenApply的区别就是没有返回值
     */
    private static void ThenAcceptTest() {
        CompletableFuture.supplyAsync(CompletableFutureTest::getList)
                .thenAccept(strList -> strList.stream().forEach(m -> System.out.println(m)));
    }

    /**
     * 有返回值
     */
    private static void ThenApplyTest() throws InterruptedException, ExecutionException {
        CompletableFuture<Integer> result = CompletableFuture.supplyAsync(CompletableFutureTest::randomInteger).thenApply((i) -> i * 8);
        System.out.println(result.get());
    }

    private static void WhenCompleteTest() {
        CompletableFuture<String> cf1 = CompletableFuture.supplyAsync(CompletableFutureTest::test1);
        CompletableFuture<String> cf2 = cf1.whenComplete((cf1_val, e) ->
                System.out.println(String.format("value:%s, exception:%s", cf1_val, e)));
        System.out.println(cf2.join());
    }

    private static String test1() {
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "test1";
    }

    public static Integer randomInteger() {
        return 10;
    }

    public static List<String> getList() {
        return Arrays.asList("a", "b");
    }
}
